package com.ec.auth.config;

import com.ec.common.utils.Threads;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 线程池配置
 **/
@Configuration
public class ThreadPoolConfig {
    // 核心线程池大小
    private final int corePoolSize = 50;

//    @Bean(name = "threadPoolTaskExecutor")
//    public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
//        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//        // 最大可创建的线程数
//        int maxPoolSize = 200;
//        executor.setMaxPoolSize(maxPoolSize);
//        executor.setCorePoolSize(corePoolSize);
//        // 队列最大长度
//        int queueCapacity = 1000;
//        executor.setQueueCapacity(queueCapacity);
//        // 线程池维护线程所允许的空闲时间
//        int keepAliveSeconds = 300;
//        executor.setKeepAliveSeconds(keepAliveSeconds);
//        // 线程池对拒绝任务(无线程可用)的处理策略
//        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
//        return executor;
//    }

    /**
     * 执行周期性或定时任务
     */
    @Bean(name = "scheduledExecutorService")
    protected ScheduledExecutorService scheduledExecutorService() {

        /*
         *  创建了一个线程工厂 basicThreadFactory，用于生成线程池中的线程。
         */
        BasicThreadFactory basicThreadFactory = new BasicThreadFactory.Builder()
                // 指定了线程命名模式
                .namingPattern("schedule-pool-%d")
                // 将线程标记为守护线程---指在主线程（或其他非守护线程）运行结束时，它会被强制终止，而不管它是否执行完毕。
                // 守护线程的存在不会阻止程序的正常执行。它们通常用于在后台执行一些任务，但不是程序中的关键部分。
                .daemon(true)
                .build();

        /*
         * 线程池大小为 corePoolSize
         */
        return new ScheduledThreadPoolExecutor(corePoolSize, basicThreadFactory) {
            /**
             * 重写 after方法
             * 在每个任务执行结束后被调用
             */
            @Override
            protected void afterExecute(Runnable r, Throwable t) {
                super.afterExecute(r, t);
                // 实现打印异常信息
                Threads.printException(r, t);
            }
        };
    }
}
